﻿using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using Sinacor.Infra.Service.Common;
using Sinacor.Infra.Common.Exceptions;
using Sinacor.Infra.Service.ExceptionHandling;
using Sinacor.Servico.Bovespa.Corretagem.BusinessEntity;
using Sinacor.Infra.Service.Validation;
using Sinacor.Servico.Bovespa.Cliente.BusinessEntity.Parameter;


namespace Sinacor.Servico.Bovespa.Corretagem.BusinessLogic
{
    public class FormadorMercado : BaseBusinessLogic
    {
        #region Constantes de Erro
        private const int ALTERARFORMADORMERCADO_REQUEST_NULO = 109188;
        private const int INCLUIRFORMADORMERCADO_REQUEST_NULO = 109187;
        private const int APELIDOCLIENTEINVALIDO = 109176;
        private const int DATAFINALMENORQUEDATAINICIAL = 109180;
        private const int ATIVOINVALIDONOPERIODO = 109181;
        private const int DATAINICIALMAIORQUEULTIMADATACADASTRADA = 109189;
        private const int PERCENTUALDESCONTOMENORQUECEM = 109186;
        private const int FORMADORMERCADODUPLICADO = 109207;
        #endregion

        #region Construtor

        private Sinacor.Servico.Bovespa.Corretagem.ResourceAccess.FormadorMercado _formadormercado;
        private ResourceAccess.FormadorMercado raFormadorMercado = null;
        public FormadorMercado()
            : base()
        {
            _formadormercado = new Sinacor.Servico.Bovespa.Corretagem.ResourceAccess.FormadorMercado();
        }

        #endregion

        #region Métodos

        public void AlterarFormadoresMercados(List<BusinessEntity.FormadorMercado> entityList)
        {
            //Para cada item, chamar o método AlterarFormadorMercado para efetuar a alteração
            foreach (BusinessEntity.FormadorMercado entity in entityList)
            {
                this.AlterarFormadorMercado(entity);
            }
        }

        public void AlterarFormadorMercado(BusinessEntity.FormadorMercado entity)
        {
            //Verifica se contém informações a serem alteradas
            if (entity == null)
                throw new BusinessException(ALTERARFORMADORMERCADO_REQUEST_NULO);

            //Valida as informações a serem alteradas
            this.ValidarFormadorMercado(entity);

            raFormadorMercado = new Sinacor.Servico.Bovespa.Corretagem.ResourceAccess.FormadorMercado();
            raFormadorMercado.AlterarFormadorMercado(entity);
        }

        public List<BusinessEntity.FormadorMercado> ConsultarConflitoPeriodo(BusinessEntity.FormadorMercado entity)
        {
            raFormadorMercado = new Sinacor.Servico.Bovespa.Corretagem.ResourceAccess.FormadorMercado();
            return raFormadorMercado.ConsultarConflitoPeriodo(entity);
        }

        public List<BusinessEntity.FormadorMercado> ConsultarFormadoresMercados(BusinessEntity.Parameter.FiltroFormadorMercado parameter)
        {
            raFormadorMercado = new Sinacor.Servico.Bovespa.Corretagem.ResourceAccess.FormadorMercado();
            return raFormadorMercado.ConsultarFormadoresMercado(parameter);
        }

        public void ExcluirFormadoresMercados(List<BusinessEntity.FormadorMercado> parameterList)
        {
            //Para cada item, chamar o método ExcluirFormadorMercado para efetuar a exclusão
            foreach (BusinessEntity.FormadorMercado parameter in parameterList)
            {
                this.ExcluirFormadorMercado(parameter);
            }

        }

        public void ExcluirFormadorMercado(BusinessEntity.FormadorMercado parameter)
        {
            raFormadorMercado = new Sinacor.Servico.Bovespa.Corretagem.ResourceAccess.FormadorMercado();
            raFormadorMercado.ExcluirFormadorMercado(parameter);
        }

        public void ExecutarTransacoesFormadorMercado(List<BusinessEntity.FormadorMercado> inclusaoList, List<BusinessEntity.FormadorMercado> exclusaoList, List<BusinessEntity.FormadorMercado> alteracaoList)
        {
            //Incluir formadores de mercado passando a lista de inclusão
            this.IncluirFormadoresMercados(inclusaoList);

            //Excluir formadores de mercado passando a lista de exclusão
            this.ExcluirFormadoresMercados(exclusaoList);

            //Alterar formadores de mercado passando a lista de alteração
            this.AlterarFormadoresMercados(alteracaoList);
        }

        public void IncluirFormadoresMercados(List<BusinessEntity.FormadorMercado> entityList)
        {
            //Para cada item, chamar o método IncluirFormadorMercado para efetuar a inclusão
            foreach (BusinessEntity.FormadorMercado entity in entityList)
            {
                this.IncluirFormadorMercado(entity);
            }
        }

        public void IncluirFormadorMercado(BusinessEntity.FormadorMercado entity)
        {
            if (entity == null)
                throw new BusinessException(INCLUIRFORMADORMERCADO_REQUEST_NULO);

            //Validar Formador Mercado
            this.ValidarFormadorMercado(entity);

            //Validação do cliente acessando o serviço de cliente
            Sinacor.Servico.Bovespa.Cliente.BusinessLogic.Cliente blCliente = new Sinacor.Servico.Bovespa.Cliente.BusinessLogic.Cliente();
            Sinacor.Servico.Bovespa.Cliente.BusinessEntity.Cliente entityCliente = null;
            //Consultar Apelido do Cliente
            FiltroClientePorApelido filtroApelido = new FiltroClientePorApelido();
            filtroApelido.ApelidoCliente = entity.ApelidoCliente;
            entityCliente = blCliente.ConsultarPorApelido(filtroApelido);
            if (entityCliente == null)
                throw new BusinessException(APELIDOCLIENTEINVALIDO);
            entity.CodigoCliente = entityCliente.Codigo;


            //Verifica se a data final é menor que a data inicial
            if (DateTime.Compare(entity.DataFinal.Value, entity.DataInicial.Value  ) == -1)
                throw new BusinessException(DATAFINALMENORQUEDATAINICIAL);


            //Consultar Ativo no periodo
            Sinacor.Servico.Bovespa.Titulo.BusinessLogic.Titulo blTitulo = new Sinacor.Servico.Bovespa.Titulo.BusinessLogic.Titulo();
            Sinacor.Servico.Bovespa.Titulo.BusinessEntity.Titulo entityTitulo = null;
            Sinacor.Servico.Bovespa.Titulo.BusinessEntity.Titulo parameterTitulo = new Sinacor.Servico.Bovespa.Titulo.BusinessEntity.Titulo();
            parameterTitulo.Codigo = entity.Ativo;
            parameterTitulo.DataOrdem = entity.DataInicial;
            entityTitulo = blTitulo.ConsultarTituloCodigo(parameterTitulo);
            if (entityTitulo == null)
            {
                throw new BusinessException(ATIVOINVALIDONOPERIODO);
            }
            
            if (entityTitulo != null)
            {
                entity.Isin = entityTitulo.CodigoISIN;
                //entity.TipoMercado = (Sinacor.Servico.Bovespa.Corretagem.BusinessEntity.Enum.TipoMercado)entityTitulo.TipoMercado;                
            }

            //Consultar conflito formador mercado
            List<Sinacor.Servico.Bovespa.Corretagem.BusinessEntity.FormadorMercado> listaFormador = null;
            listaFormador = this.ConsultarConflitoPeriodo(entity);
            if (!listaFormador.Count.Equals(0) && entity.DataInicial.HasValue)
            {
                if (entity.DataInicial.Value > listaFormador[0].DataFinal)
                    throw new BusinessException(DATAINICIALMAIORQUEULTIMADATACADASTRADA);
            }

            //Verificar Duplicidade
            if (this.ValidarExistenciaFormadorMercado(entity))
                throw new BusinessException(FORMADORMERCADODUPLICADO);

            raFormadorMercado = new Sinacor.Servico.Bovespa.Corretagem.ResourceAccess.FormadorMercado();
            raFormadorMercado.IncluirFormadorMercado(entity);
        }

        private void ValidarFormadorMercado(BusinessEntity.FormadorMercado entity)
        {
            SinacorValidation validar = new SinacorValidation();
            validar.Validate<BusinessEntity.FormadorMercado>(entity);
            validar.Validate();
            validar = null;

            if (entity.PercentualDesconto.Value > 100)
                throw new BusinessException(PERCENTUALDESCONTOMENORQUECEM);
        }

        private bool ValidarExistenciaFormadorMercado(BusinessEntity.FormadorMercado entity)
        {
            BusinessEntity.Parameter.FiltroFormadorMercado filtro = new Sinacor.Servico.Bovespa.Corretagem.BusinessEntity.Parameter.FiltroFormadorMercado();
            filtro.ApelidoCliente = entity.ApelidoCliente;
            filtro.Ativo = entity.Ativo;
            filtro.CodigoCliente = entity.CodigoCliente;
            filtro.DataInicial = entity.DataInicial;

            List<BusinessEntity.FormadorMercado> retorno = null;
            retorno = this.ConsultarFormadoresMercados(filtro);
            return (retorno.Count > 0);
        }

        #endregion
    }
}
